var EyeBall = {
    
    connection: null,
    
    showTraffic: function(body, type) {
	if (body.childNodes.length > 0) {
	    var console = $("#console").get(0);
	    var atBottom = console.scrollTop >= (console.scrollHeight - console.clientHeight);

	    $.each(body.childNodes, function() {
		$("#console").append("<div class='" + type + "'>" + EyeBall.prettyXml(this, 0) + "</div>");
	    });

	    if (atBottom) console.scrollTop = console.scrollHeight;
	}
    },

    textToXml: function(text) {
	var parser = new DOMParser();
	var doc = parser.parseFromString(text, "text/xml");
	
	var elem = doc.documentElement;
	if ($(elem).filter("parsererror").length > 0) { throw { type: "Parse Error" }; }
	return elem;
    },

    prettyXml: function(xml, level) {
        var i, j;
        var result = [];

        result.push("<div class='xml-indent" + level + "'>");
        result.push("<span class='xml-punc'>&lt;</span>");
        result.push("<span class='xml-tag'>");
        result.push(xml.tagName);
        result.push("</span>");

        // attributes
        var attrs = xml.attributes;
        var attr_lead = []
        for (i = 0; i < xml.tagName.length + 1; i++) {
            attr_lead.push("&nbsp;");
        }
        attr_lead = attr_lead.join("");

        for (i = 0; i < attrs.length; i++) {
            result.push(" <span class='xml-attr-name'>");
            result.push(attrs[i].nodeName);
            result.push("</span><span class='xml-punc'>='</span>");
            result.push("<span class='xml-attr-value'>");
            result.push(attrs[i].nodeValue);
            result.push("</span><span class='xml-punc'>'</span>");

            if (i !== attrs.length - 1) {
                result.push("</div><div class='xml-indent" + level + "'>");
                result.push(attr_lead);
            }
        }

        if (xml.childNodes.length === 0) {
            result.push("<span class='xml-punc'>/&gt;</span></div>");
        } else {
            result.push("<span class='xml-punc'>&gt;</span></div>");

            // children
            $.each(xml.childNodes, function () {
                if (this.nodeType === 1) {
                    result.push(EyeBall.prettyXml(this, level + 1));
                } else if (this.nodeType === 3) {
                    result.push("<div class='xml-text xml-indent" + 
                                (level + 1) + "'>");
                    result.push(this.nodeValue);
                    result.push("</div>");
                }
            });
            
            result.push("<div class='xml xml-indent" + level + "'>");
            result.push("<span class='xml-punc'>&lt;/</span>");
            result.push("<span class='xml-tag'>");
            result.push(xml.tagName);
            result.push("</span>");
            result.push("<span class='xml-punc'>&gt;</span></div>");
        }
        
        return result.join("");
    }

};

$(document).ready(function() {
    $("#login-dialog").dialog({
	autoOpen: true,
	draggable: false,
	modal: true,
	title: "Connect to XMPP",
	buttons: {
	    "Connect": function() {
		$(document).trigger("connect", {
		    server: $("#server").val(),
		    jid: $("#jid").val(),
		    password: $("#password").val()
		});
		$("#password").val("");
		$(this).dialog("close");
	    }
	}
    });
    bindEvent();
});

$(document).bind("connect", function(ev, data) {
    var conn = new Strophe.Connection(data.server);
    conn.xmlInput = function(body) {
	EyeBall.showTraffic(body, "incoming");
    };
    conn.xmlOutput = function(body) {
	EyeBall.showTraffic(body, "outgoing");
    };

    conn.connect(data.jid, data.password, function(status) {
	if (status === Strophe.Status.CONNECTED) {
	    $(document).trigger("connected");
	} else if (status === Strophe.Status.DISCONNECTED) {
	    $(document).trigger("disconnected");
	}
    });

    EyeBall.connection = conn;
});

$(document).bind("connected", function() {
    enable("disconnect-button");
    $("#input").removeClass("disabled").removeAttr("disabled");
});

$(document).bind("disconnected", function() {
    disable("disconnect-button");
    $("#input").addClass("disabled").attr("disabled", "disabled");
});

function bindEvent() {
    $("#disconnect-button").click(function() {
	EyeBall.connection.disconnect();
	EyeBall.connection = null;
    });

    $("#send-button").click(function() {
	var xmlText = $("#input").val();
	if (xmlText.length === 0) return;
	try {
	    parseAndSend(xmlText);
	} catch (e) {
	    $("#input").animate({backgroundColor: "#faa"}, 200);
	}
	$("#input").val("");
    });

    $("#input").keypress(function() {
	$(this).css({backgroundColor: "#fff"});
    });
}

function parseAndSend(xmlText) {
    var xmlToSend = null;
    if (xmlText[0] === "<") {
	xmlToSend = EyeBall.textToXml(xmlText);
    } else {
	xmlToSend = eval(xmlText);
    }	
    EyeBall.connection.send(xmlToSend);
}

function enable(elementId) { $("#" + elementId).removeAttr("disabled"); }
function disable(elementId) { $("#" + elementId).attr("disabled", "disabled"); }

